
package org.sevenblindmice.make24;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

class MyAdapter extends BaseAdapter implements View.OnClickListener, OnItemClickListener {
    @SuppressWarnings("serial")
    private static class RowData implements Serializable {
        int[] numbers;
        String answer;
        String error;
    }

    private final LayoutInflater mInflater;
    private final ArrayList<RowData> mData;
    private final MyListView mListView;
    private final TextView mErrorView;
    private final Random r = new Random();
    private Integer textColor;

    MyAdapter(LayoutInflater inflater, MyListView lv, TextView errorView, Bundle savedInstanceState) {
        mInflater = inflater;
        mListView = lv;
        mErrorView = errorView;
        mData = restore(savedInstanceState);
        if (mData.isEmpty()) {
            newRow();
        }
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public RowData getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v;
        if (convertView == null) {
            v = mInflater.inflate(R.layout.row, parent, false);
        } else {
            v = convertView;
        }

        TextView numbersText = (TextView) v.findViewById(R.id.numbers);
        TextView answerText = (TextView) v.findViewById(R.id.answer);
        RowData row = getItem(position);
        numbersText.setText(String.format("%d %d %d %d", row.numbers[0], row.numbers[1],
                row.numbers[2], row.numbers[3]));

        if (row.answer != null) {
            answerText.setText(row.answer);

            if (row.error != null) {
                answerText.setTextColor(0xFFFF0000);
            } else {
                answerText.setTextColor(0xFF008000);
            }
        } else {
            if (textColor == null) {
                textColor = answerText.getCurrentTextColor();
            }
            answerText.setText("");
            answerText.setTextColor(textColor);
        }

        if (position == getLastIndex()) {
            answerText.setBackgroundColor(0xFFFFFFFF);
        } else {
            answerText.setBackgroundColor(0);
        }

        return v;
    }

    private void validate(RowData row) {
        Validator validator = new Validator(row.numbers, row.answer);
        if (!validator.validate()) {
            row.error = validator.getError();
            setError(row.error);
        } else {
            setError(null);
        }
    }

    private void setError(String text) {
        mErrorView.setText(text);
    }

    @Override
    public boolean hasStableIds() {
        return false; // required for 2nd row!
    }

    private void newRow() {
        RowData newRow = new RowData();
        newRow.numbers = new int[4];
        newRow.numbers[0] = r.nextInt(10) + 1;
        newRow.numbers[1] = r.nextInt(10) + 1;
        newRow.numbers[2] = r.nextInt(10) + 1;
        newRow.numbers[3] = r.nextInt(10) + 1;
        Arrays.sort(newRow.numbers);
        mData.add(newRow);
    }

    public void save(Bundle outState) {
        outState.putSerializable("data", mData);
    }

    @SuppressWarnings("unchecked")
    public ArrayList<RowData> restore(Bundle savedInstanceState) {
        ArrayList<RowData> data = null;
        if (savedInstanceState != null) {
            Serializable serializable = savedInstanceState.getSerializable("data");
            if (serializable instanceof ArrayList<?>) {
                data = (ArrayList<RowData>) serializable;
            }
        }
        if (data == null) {
            data = new ArrayList<RowData>();
        }
        return data;
    }

    @Override
    public void onClick(final View v) {
        if (mListView.scrollToPosition(getLastIndex())) {
            v.postDelayed(new Runnable() {
                @Override
                public void run() {
                    onClick(v);
                }
            }, 100);
            return;
        }

        TextView answerText = getAnswerText();
        if (answerText == null) {
            return;
        }
        String answer = answerText.getText().toString();

        switch (v.getId()) {
            case R.id.clr:
                answerText.setText("");
                break;
            case R.id.del:
                if (!answer.isEmpty()) {
                    answer = answer.substring(0, answer.length() - 1);
                }
                answerText.setText(answer);
                break;
            case R.id.enter:
                RowData row = getItem(getLastIndex());
                row.answer = answer;
                validate(row);
                if (getCount() < 20) {
                    newRow();
                }
                v.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        notifyDataSetChanged();
                        mListView.scrollToPosition(getLastIndex());
                    }
                }, 100);
                break;
            default:
                answer = answer + ((Button) v).getText();
                answerText.setText(answer);
        }
    }

    private TextView getAnswerText() {
        int index = getLastIndex() - mListView.getFirstVisiblePosition();
        View lastRow = mListView.getChildAt(index);
        if (lastRow == null) {
            Log.i("DD", "getChildAt(" + index + ") is null. Last index=" + getLastIndex());
            return null;
        }
        return (TextView) lastRow.findViewById(R.id.answer);
    }

    protected int getLastIndex() {
        return getCount() - 1;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        RowData row = getItem(position);
        setError(row.error);
    }
}
